/**
 * ApnsPush.java 
 * Copyright © 2015-3015, 杭州泊享网络科技有限公司
 * 
 * @author Liu Tao
 * @create 2014年11月1日
 */
package com.pshare.tool;

import java.util.List;

import javapns.communication.exceptions.CommunicationException;
import javapns.communication.exceptions.KeystoreException;
import javapns.devices.Device;
import javapns.devices.exceptions.InvalidDeviceTokenFormatException;
import javapns.devices.implementations.basic.BasicDevice;
import javapns.json.JSONException;
import javapns.notification.AppleNotificationServer;
import javapns.notification.AppleNotificationServerBasicImpl;
import javapns.notification.Payload;
import javapns.notification.PushNotificationManager;
import javapns.notification.PushNotificationPayload;
import javapns.notification.PushedNotification;
import javapns.notification.PushedNotifications;
import javapns.notification.transmission.NotificationThreads;

/**
 * 自定义APNS推送接口
 */
public class ApnsPush {
	
	private static final String HYPHEN = "-";
	
	public static PushedNotifications payload(Payload payload, Object keystore, String password, boolean production, Object devices) throws CommunicationException, KeystoreException {
		return sendPayload(payload, keystore, password, production, devices);
	}
	
	private static PushedNotifications sendPayload(Payload payload, Object keystore, String password, boolean production, Object devices) throws CommunicationException, KeystoreException {
		PushedNotifications notifications = new PushedNotifications();
		if (payload == null) return notifications;
		PushNotificationManager pushManager = new PushNotificationManager();
		try {
			AppleNotificationServer server = new AppleNotificationServerBasicImpl(keystore, password, production);
			pushManager.initializeConnection(server);
			List<Device> deviceList = ApnsDeviceHandler.asDevices(devices, payload);
			notifications.setMaxRetained(deviceList.size());
			for (Device device : deviceList) {
				Integer badge = hanleDeviceStr(device);
				try {
					BasicDevice.validateTokenFormat(device.getToken());
					if (payload instanceof PushNotificationPayload) {
						try {
							((PushNotificationPayload) payload).addBadge(badge + 1);  // 添加未读消息条数
						} catch (JSONException e) {
						}
					}
					PushedNotification notification = pushManager.sendNotification(device, payload, false);
					notifications.add(notification);
				} catch (InvalidDeviceTokenFormatException e) {
					notifications.add(new PushedNotification(device, payload, e));
				}
			}
		} finally {
			try {
				pushManager.stopConnection();
			} catch (Exception e) {
			}
		}
		return notifications;
	}
	
	public static PushedNotifications payload(Payload payload, Object keystore, String password, boolean production, int numberOfThreads, Object devices) throws Exception {
		if (numberOfThreads <= 0) return sendPayload(payload, keystore, password, production, devices);
		AppleNotificationServer server = new AppleNotificationServerBasicImpl(keystore, password, production);
		List<Device> deviceList = ApnsDeviceHandler.asDevices(devices, payload);
		NotificationThreads threads = new NotificationThreads(server, payload, deviceList, numberOfThreads);
		threads.start();
		try {
			threads.waitForAllThreads(true);
		} catch (InterruptedException e) {
		}
		return threads.getPushedNotifications(true);
	}
	
	/**
	 * 针对"deviceToken-count"格式的device信息进行处理
	 * @param device
	 * @param token
	 * @return Integer
	 */
	private static Integer hanleDeviceStr(Device device) {
		Integer badge = 0;
		String token = device.getToken();
		if(token.indexOf(HYPHEN) == -1) {
			
		} else {
			String[] values = token.split(HYPHEN);
			token = values[0];
			badge = Integer.parseInt(values[1]);
			device.setToken(token);
		}

		return badge;
	}
	
}
